new function () {
    'use strict';
    const GradientDrawable = android.graphics.drawable.GradientDrawable;

    const resources = context.getResources();
    const scale = resources.getDisplayMetrics().density;
    const config = resources.getConfiguration();

    const status_bar_height = resources.getDimensionPixelSize(
        resources.getIdentifier('status_bar_height', 'dimen', 'android')
    );

    const navigation_bar_height = resources.getDimensionPixelSize(
        resources.getIdentifier('navigation_bar_height', 'dimen', 'android')
    );

    function px2dp(px) {
        return Math.floor(px / scale + .5);
    }

    function dp2px(dp) {
        return Math.floor(dp * scale + .5);
    }

    /**
     * 创建样式
     * @param {number} radius  
     * @param {number|null} shape 
     * @param {string|null} fillColor 
     * @param {Array.<number,string,number,number>} strokes
     * @returns 
     */
    function createShape(radius, shape, fillColor, strokes) {
        radius = radius === -1 ? Number.MAX_VALUE : dp2px(radius) || 0;
        shape = shape || 0;
        let gd = new GradientDrawable();
        if (fillColor) gd.setColor($colors.parseColor(fillColor));
        gd.setCornerRadius(radius);
        gd.setShape(shape);
        if (Array.isArray(strokes)) {
            if (strokes[1]) strokes[1] = $colors.parseColor(strokes[1]);
            gd.setStroke.apply(gd, [0, $colors.TRANSPARENT, 0, 0].map((s, i) => strokes[i] || s));
        }
        return gd;
    }

    /**
     * 代理对象单个键值
     * @param {Object} obj object对象
     * @param {string} key 键名
     * @param {*} defval 默认值
     * @param {callback} changeCallback 键值发生变化回调方法
     */
    function def(obj, key, defval, changeCallback) {
        Object.defineProperty(obj, key, {
            get(name) {
                return defval;
            },
            set(name, val) {
                defval = val;
                changeCallback(val);
            }
        });
    }

    function defineValue(key, defval, callback) {
        callback = callback || Function;
        callback.bind(this);
        let value = defval === undefined ? this[key] : defval;
        let lastValue = value;
        Object.defineProperty(this, key, {
            get() {
                return value;
            },
            set(newval) {
                if (value !== newval) {
                    lastValue = value;
                    value = newval;
                    callback(value, lastValue);
                }
            }
        });
    }

    /**
     * 是否横屏
     */
    function isHorizontalScreen() {
        return config.orientation === 2;
    }

    module.exports = {
        dp2px,
        px2dp,
        createShape,
        def,
        defineValue,
        status_bar_height,
        navigation_bar_height,
        isHorizontalScreen
    }
}